﻿using BJoin.Application.BObject;
using BJoin.Application.Dto;
using BJoin.Application.Entity;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace BJoin.Application.IManager
{
    /// <summary>
    /// POCO Contract for common
    /// </summary>
    /// <typeparam name="TDto"></typeparam>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    /// <typeparam name="TExt"></typeparam>
    public interface IManager<TDto, TEntity>
        where TDto : ResDto where TEntity : BaseEntity
    {
        #region Common Async

        /// <summary>
        /// 获取总数
        /// </summary>
        /// <param name="filter">筛选对象</param>
        /// <returns>long</returns>
        Task<long> CountAsync<TFilter>(TFilter filter, Func<TFilter, object> filterTranslator = null) where TFilter : ReqFilter;

        /// <summary>
        /// 获取总数(表达式)
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns>long</returns>
        Task<long> CountAsync(Expression<Func<TEntity, bool>> expression);

        /// <summary>
        /// 记录筛选
        /// </summary>
        /// <param name="filter">筛选对象</param>
        /// <param name="firstResult">第几条</param>
        /// <param name="maxResults">最大记录数</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <param name="dataTranslator">数据翻译器</param>
        /// <param name="orderBy">排序</param>
        /// <returns>实体集合</returns>
        Task<IEnumerable<TDto>> FilterAsync<TFilter>(TFilter filter, int? firstResult = null, int? maxResults = null, string[] orderBy = null, Func<TFilter, object> filterTranslator = null, Action<List<TDto>> dataTranslator = null) where TFilter : ReqFilter;

        /// <summary>
        /// 记录筛选(表达式)
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="firstResult">第几条</param>
        /// <param name="maxResults">最大记录数</param>
        /// <param name="orderBy">排序</param>
        /// <param name="dataTranslator">数据翻译器</param>
        /// <returns>实体集合</returns>
        Task<IEnumerable<TDto>> FilterAsync(Expression<Func<TEntity, bool>> expression, int? firstResult = null, int? maxResults = null, string[] orderBy = null, Action<List<TDto>> dataTranslator = null);

        /// <summary>
        /// 分页记录筛选
        /// </summary>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">每页数目</param>
        /// <param name="filter">筛选对象</param>
        /// <param name="orderBy">排序</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <param name="dataTranslator">数据翻译器</param>
        /// <returns>分页实体集合</returns>
        Task<ResPagingDto<TDto>> PagingFilterAsync<TFilter>(TFilter filter, int pageIndex = 0, int pageSize = 20, string[] orderBy = null, Func<TFilter, object> filterTranslator = null, Action<List<TDto>> dataTranslator = null) where TFilter : ReqFilter;

        /// <summary>
        /// 分页记录筛选(表达式)
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">每页数目</param>
        /// <param name="orderBy">排序</param>
        /// <param name="dataTranslator">数据翻译器</param>
        /// <returns>分页实体集合</returns>
        Task<ResPagingDto<TDto>> PagingFilterAsync(Expression<Func<TEntity, bool>> expression, int pageIndex = 0, int pageSize = 20, string[] orderBy = null, Action<List<TDto>> dataTranslator = null);

        /// <summary>
        /// 条件更新(支持单一或多个属性)
        /// </summary>
        /// <param name="dto">更新实体</param>
        /// <param name="filter">筛选对象</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateSetAsync<TFilter, TUpdateDto>(TUpdateDto updateDto, TFilter filter, Func<TFilter, object> filterTranslator = null) where TUpdateDto : ReqUpdateDto;


        /// <summary>
        /// 条件更新（全部属性，支持Null）
        /// </summary>
        /// <param name="dto">更新实体</param>
        /// <param name="filter">筛选对象</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateAsync<TFilter, TUpdateDto>(TUpdateDto updateDto, TFilter filter, Func<TFilter, object> filterTranslator = null) where TUpdateDto : ReqUpdateDto where TFilter : ReqFilter;

        /// <summary>
        /// 条件删除
        /// </summary>
        /// <param name="filter">筛选对象</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync<TFilter>(TFilter filter, Func<TFilter, object> filterTranslator = null) where TFilter : ReqFilter;

        /// <summary>
        /// 条件删除（表达式）
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> expression);
        #endregion
    }
    /// <summary>
    /// POCO Contract Have not TKey
    /// </summary>
    /// <typeparam name="TDto"></typeparam>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    /// <typeparam name="TExt"></typeparam>
    public interface IPocoManager<TDto, TEntity>:IManager<TDto,TEntity>
        where TDto : ResDto where TEntity : BaseEntity
    {
        #region Common Async
        /// <summary>
        /// 单条新增
        /// </summary>
        /// <param name="dto">新增实体</param>
        /// <returns>id</returns>
        Task<bool> AddAsync<TAddDto>(TAddDto addDto) where TAddDto : ReqAddDto;

        /// <summary>
        /// 批量新增(小批量，超过1000条需开启事务)
        /// </summary>
        /// <param name="addDtos">新增实体集合</param>
        /// <returns>true/false</returns>
        Task<bool> AddManyAsync<TAddDto>(IEnumerable<TAddDto> addDtos) where TAddDto : ReqAddDto;
        #endregion
    }

    /// <summary>
    /// POCO Contract Have TKey
    /// </summary>
    /// <typeparam name="TDto"></typeparam>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    /// <typeparam name="TExt"></typeparam>
    public interface IPocoManager<TDto, TEntity, TKey>:IManager<TDto,TEntity>
        where TDto : ResDto<TKey> where TEntity : BaseEntity<TKey>
    {
        #region Common Async

        /// <summary>
        /// 单条查询
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="dataTranslator">数据翻译器</param>
        /// <returns>动态对象</returns>
        Task<TDto> GetSingleAsync(TKey id, Action<TDto> dataTranslator = null);

        /// <summary>
        /// 单条新增
        /// </summary>
        /// <param name="dto">新增实体</param>
        /// <returns>id</returns>
        Task<TKey> AddAsync<TAddDto>(TAddDto addDto) where TAddDto : ReqAddDto;

        /// <summary>
        /// 批量新增(小批量，超过1000条需开启事务)
        /// </summary>
        /// <param name="addDtos">新增实体集合</param>
        /// <returns>true/false</returns>
        Task<IEnumerable<TKey>> AddManyAsync<TAddDto>(IEnumerable<TAddDto> addDtos) where TAddDto : ReqAddDto;


        /// <summary>
        /// ID更新(支持单一或多个属性)
        /// </summary>
        /// <param name="dto">更新实体</param>
        /// <param name="id">id</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateSetAsync<TUpdateDto>(TUpdateDto updateDto, TKey id) where TUpdateDto : ReqUpdateDto;
        
        /// <summary>
        /// ID更新（全部属性，支持Null）
        /// </summary>
        /// <param name="dto">更新实体</param>
        /// <param name="id">id</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateAsync<TUpdateDto>(TUpdateDto updateDto, TKey id) where TUpdateDto : ReqUpdateDto;

        /// <summary>
        /// 根据ID(支持多个)删除
        /// </summary>
        /// <param name="id">id</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync(TKey[] id);
        #endregion
    }
    /// <summary>
    /// POCO Contract Have TKey and TExt
    /// </summary>
    /// <typeparam name="TDto"></typeparam>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    /// <typeparam name="TExt"></typeparam>
    public interface IPocoManager<TDto, TEntity, TKey,TExt> 
        where TDto : ResDto<TKey,TExt> where TEntity : BaseEntity<TKey, TExt> where TExt:BObjExt
    {
        #region Common Async

        /// <summary>
        /// 获取总数
        /// </summary>
        /// <param name="filter">筛选对象</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <returns>long</returns>
        Task<long> CountAsync<TFilter>(TFilter filter, Func<TFilter,object> filterTranslator = null) where TFilter : ReqFilter<TKey,TExt>;

        /// <summary>
        /// 获取总数(表达式)
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns>long</returns>
        Task<long> CountAsync(Expression<Func<TEntity,bool>> expression);

        /// <summary>
        /// 单条查询
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="dataTranslator">数据翻译器</param>
        /// <returns>动态对象</returns>
        Task<TDto> GetSingleAsync(TKey id, Action<TDto> dataTranslator = null);

        /// <summary>
        /// 记录筛选
        /// </summary>
        /// <param name="filter">筛选对象</param>
        /// <param name="firstResult">第几条</param>
        /// <param name="maxResults">最大记录数</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <param name="dataTranslator">数据翻译器</param>
        /// <param name="orderBy">排序</param>
        /// <returns>实体集合</returns>
        Task<IEnumerable<TDto>> FilterAsync<TFilter>(TFilter filter, int? firstResult = null, int? maxResults = null, string[] orderBy = null,  Func<TFilter,object> filterTranslator = null, Action<List<TDto>> dataTranslator = null) where TFilter : ReqFilter<TKey,TExt>;

        /// <summary>
        /// 记录筛选(表达式)
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="firstResult">第几条</param>
        /// <param name="maxResults">最大记录数</param>
        /// <param name="orderBy">排序</param>
        /// <param name="dataTranslator">数据翻译器</param>
        /// <returns>实体集合</returns>
        Task<IEnumerable<TDto>> FilterAsync(Expression<Func<TEntity, bool>> expression, int? firstResult = null, int? maxResults = null, string[] orderBy = null, Action<List<TDto>> dataTranslator = null);

        /// <summary>
        /// 分页记录筛选
        /// </summary>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">每页数目</param>
        /// <param name="filter">筛选对象</param>
        /// <param name="orderBy">排序</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <param name="dataTranslator">数据翻译器</param>
        /// <returns>分页实体集合</returns>
        Task<ResPagingDto<TDto>> PagingFilterAsync<TFilter>(TFilter filter, int pageIndex = 0, int pageSize = 20, string[] orderBy = null, Func<TFilter,object> filterTranslator = null, Action<List<TDto>> dataTranslator = null) where TFilter : ReqFilter<TKey, TExt>;

        /// <summary>
        /// 分页记录筛选(表达式)
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">每页数目</param>
        /// <param name="orderBy">排序</param>
        /// <param name="dataTranslator">数据翻译器</param>
        /// <returns>分页实体集合</returns>
        Task<ResPagingDto<TDto>> PagingFilterAsync(Expression<Func<TEntity, bool>> expression, int pageIndex = 0, int pageSize = 20, string[] orderBy=null, Action<List<TDto>> dataTranslator = null);

        /// <summary>
        /// 单条新增
        /// </summary>
        /// <param name="dto">新增实体</param>
        /// <returns>id</returns>
        Task<TKey> AddAsync<TAddDto>(TAddDto addDto) where TAddDto : ReqAddDto<TExt>;

        /// <summary>
        /// 批量新增(小批量，超过1000条需开启事务)
        /// </summary>
        /// <param name="addDtos">新增实体集合</param>
        /// <returns>true/false</returns>
        Task<IEnumerable<TKey>> AddManyAsync<TAddDto>(IEnumerable<TAddDto> addDtos) where TAddDto : ReqAddDto<TExt>;

        /// <summary>
        /// ID更新(支持单一或多个属性)
        /// </summary>
        /// <param name="dto">更新实体</param>
        /// <param name="id">id</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateSetAsync<TUpdateDto>(TUpdateDto updateDto, TKey id) where TUpdateDto:ReqUpdateDto<TExt>;

        /// <summary>
        /// 条件更新(支持单一或多个属性)
        /// </summary>
        /// <param name="dto">更新实体</param>
        /// <param name="filter">筛选对象</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateSetAsync<TFilter, TUpdateDto>(TUpdateDto updateDto, TFilter filter, Func<TFilter, object> filterTranslator = null) where TUpdateDto : ReqUpdateDto<TExt>;

        /// <summary>
        /// ID更新（全部属性，支持Null）
        /// </summary>
        /// <param name="dto">更新实体</param>
        /// <param name="id">id</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateAsync<TUpdateDto>(TUpdateDto updateDto, TKey id) where TUpdateDto : ReqUpdateDto<TExt>;

        /// <summary>
        /// 条件更新（全部属性，支持Null）
        /// </summary>
        /// <param name="dto">更新实体</param>
        /// <param name="filter">筛选对象</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateAsync<TFilter, TUpdateDto>(TUpdateDto updateDto, TFilter filter, Func<TFilter, object> filterTranslator = null) where TUpdateDto : ReqUpdateDto<TExt> where TFilter : ReqFilter<TKey, TExt>;

        /// <summary>
        /// 根据ID(支持多个)删除
        /// </summary>
        /// <param name="id">id</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync(TKey[] id);

        /// <summary>
        /// 条件删除
        /// </summary>
        /// <param name="filter">筛选对象</param>
        /// <param name="filterTranslator">筛选翻译器</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync<TFilter>(TFilter filter, Func<TFilter, object> filterTranslator = null) where TFilter : ReqFilter<TKey,TExt>;

        /// <summary>
        /// 条件删除（表达式）
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> expression);
        #endregion
    }
}
